/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package sopraim.model;

import java.sql.Date;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import sopraim.entity.Action;
import sopraim.entity.TextMessage;
import sopraim.entity.User;

/**
 *
 * @author Administrateur
 */
public class TextMessageDAO {
    
    private SessionFactory factory;
    
    public TextMessageDAO(SessionFactory factory) {
        this.factory = factory;
    }
    
    public TextMessage findById(int textMessageId) {
        Session session = null;
        TextMessage tm = null;
        session = factory.getCurrentSession();
        tm = (TextMessage) session.load(TextMessage.class, textMessageId);
        Hibernate.initialize(tm);
        session.getTransaction().commit();
        return tm;
    }
    
    public void sendMessage(User userSender, User userReceiver, String text) {
        // cree un new TextMessage
        // cree une Action (type sent)
        Session session = factory.getCurrentSession();
        session.beginTransaction();
        TextMessage tm = new TextMessage();
        tm.setMessage(text);
        tm.setSender(userSender);
        tm.setDate(new Timestamp(System.currentTimeMillis()));
        // tm.setDate TODO
        Action action = new Action();
        action.setUserReceiver(userReceiver);
        action.setMessage(tm);
        action.setType(0);
        session.save(tm);
        session.save(action);
        session.getTransaction().commit();
    }
    
    public Set<TextMessage> getNewMessages(User userReceiver) {
        // renvoie les TextMessage de type sent where userReceiver correspondant
        // modifie l'action : type = received
        Session session = factory.getCurrentSession();
        session.beginTransaction();
        List list = session.createQuery("from Action where userReceiver = :userReceiv and type = :receivedOnServer")
                .setParameter("receivedOnServer", 0)
                .setParameter("userReceiv", userReceiver).list();
        ;
        HashSet<TextMessage> tm = new HashSet<TextMessage>();
        Action a = null;
        Iterator it=list.iterator();
        while(it.hasNext()) {
            a = (Action) it.next();
            tm.add(a.getMessage());
            a.setType(1); // received on client
            session.update(a);
            
        }
        session.getTransaction().commit();
        return tm;
        
    }
    
    // place à "lu" tous les messages envoyés par lastMessageRead.getSender()
    // à UserReceiver anterieurs à lastMessageRead qui étaient
    //dans le type "received on client"
    //(last message read inclus)
    public void readMessage(User userReceiver, TextMessage lastMessageRead) {
        
        Session session = factory.getCurrentSession();
        session.beginTransaction();
        // select all messages send by the sender of lastMessageRead before the date
        Query q = session.createQuery("from TextMessage where sender = :userSender and date <= :lastMessageDate")
                .setParameter("lastMessageDate", lastMessageRead.getDate())
                .setParameter("userSender", lastMessageRead.getSender());
        
        //HashSet<Action> tm = new HashSet<Action>();
        TextMessage tm = null;
        
        if (q.iterate().hasNext()) {
            tm = (TextMessage) q.iterate().next();
            // select action of this message where userReceveiver is egal
            Query q1 = session.createQuery("from Action where userReceiver = :userReceiv and type = :receivedOnClient and message = :textMessage ")
                    .setParameter("receivedOnClient", 1)
                    .setParameter("userReceiv", userReceiver)
                    .setParameter("textMessage", tm);
            Action a = null;
            if (q1.iterate().hasNext()) {
                a = (Action) q1.iterate().next();
                a.setType(2); // read
                session.update(a);
                
            }
            session.getTransaction().commit();
            
        }
    }
    public ArrayList<TextMessage> getAllMessage(User user) {
        
        Session session = factory.getCurrentSession();
        session.beginTransaction();
        //
        List list = session.createQuery("from TextMessage where sender = :userSender")
                .setParameter("userSender", user).list();
        ArrayList<TextMessage> res = new ArrayList();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            res.add((TextMessage) it.next());
        }
        List received = session.createQuery("from Action where userReceiver = :userReceiv")
                .setParameter("userReceiv", user).list();
        it = received.iterator();
        while (it.hasNext()) {
            Action a = (Action)it.next();
            res.add(a.getMessage());
        }
        
        return res;
    }
    public ArrayList<TextMessage> getMessagesSento(User localUser, User remoteUser){
        Session session = factory.getCurrentSession();
        session.beginTransaction();
        List list = session.createQuery("from TextMessage where sender = :userSender")
                .setParameter("userSender", localUser).list();
        ArrayList<TextMessage> res = new ArrayList();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            TextMessage m = (TextMessage) it.next();
            List list2 = session.createQuery("from Action where userReceiver = :userReceiv "
                    + "and message = :textMessage ")
                    .setParameter("userReceiv", remoteUser)
                    .setParameter("textMessage", m).list();
            Iterator it2 = list2.iterator();
            while(it2.hasNext()){
                Action a = (Action)it2.next();
                TextMessage mess = a.getMessage();
                mess.getSender().setUsername("me");
                res.add(a.getMessage());
            }
        }
        return res;
    }
      public ArrayList<TextMessage> getMessagesReceivedFrom(User localUser, User remoteUser){
        Session session = factory.getCurrentSession();
        session.beginTransaction();
        List list = session.createQuery("from Action where userReceiver = :userReceiv ")
                    .setParameter("userReceiv", localUser).list();
        ArrayList<TextMessage> res = new ArrayList();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Action a = (Action)it.next();
            TextMessage m = (TextMessage) a.getMessage();
           if(m.getSender().equals(remoteUser)){
               res.add(m);
           }
        }
        return res;
    }
    
}
